package com.woniuxy.yoga.product.service.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.yoga.business.dao.model.BusinessStore;
import com.woniuxy.yoga.commons.core.model.PageInfo;
import com.woniuxy.yoga.commons.core.model.Result;
import com.woniuxy.yoga.commons.core.statedata.BusinessState;
import com.woniuxy.yoga.commons.core.statedata.CoachState;
import com.woniuxy.yoga.commons.core.statedata.ProductState;
import com.woniuxy.yoga.commons.redis.util.rediskeyutil.ProductRedisKeyUtil;
import com.woniuxy.yoga.product.client.BusinessStoreClient;
import com.woniuxy.yoga.product.client.CoachClient;
import com.woniuxy.yoga.product.client.dto.business.BusinessStoreDTO;
import com.woniuxy.yoga.product.client.dto.coach.CoachByIdDTO;
import com.woniuxy.yoga.product.dao.model.PrivateProduct;
import com.woniuxy.yoga.product.dao.mapper.PrivateProductMapper;
import com.woniuxy.yoga.product.model.dto.NormalPrivateProductDTO;
import com.woniuxy.yoga.product.model.dto.PrivateProductByIdDTO;
import com.woniuxy.yoga.product.model.dto.QueryAllPrivateProductDTO;
import com.woniuxy.yoga.product.model.exception.ProductException;
import com.woniuxy.yoga.product.model.exception.ProductExceptionCode;
import com.woniuxy.yoga.product.model.param.AddPrivateProductParam;
import com.woniuxy.yoga.product.model.param.QueryNormalPrivateProductParam;
import com.woniuxy.yoga.product.model.param.QueryPrivateProductParam;
import com.woniuxy.yoga.product.service.service.PrivateProductService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 私人产品表 服务实现类
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年12月06日
 */
@Service
public class PrivateProductServiceImpl extends ServiceImpl<PrivateProductMapper, PrivateProduct> implements PrivateProductService {

    @Autowired
    private PrivateProductMapper privateProductMapper;

    @Autowired
    private CoachClient coachClient;

    @Autowired
    private BusinessStoreClient businessStoreClient;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 新增私教产品
     * @param param
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void addPrivateProduct(AddPrivateProductParam param) throws Exception {
        //创建单锁
        RLock lock = redissonClient.getFairLock(ProductRedisKeyUtil.lockAddByPrivateProductName(param.getPrivateProductName()));
        boolean isLock = lock.tryLock(10, TimeUnit.SECONDS);
        try {
            if (!isLock){
                throw new Exception("服务器繁忙请稍后再试");
            }
            //判断查询教练是否报错
            Result<CoachByIdDTO> coachByIdDTOResult = coachClient.getCoachById(param.getCoachId());
            if (coachByIdDTOResult.getCode()!=200) throw new ProductException(coachByIdDTOResult.getCode(),coachByIdDTOResult.getMessage());
            //获取数据
            CoachByIdDTO coachByIdDTO = coachByIdDTOResult.getData();
            //判断是否为空
            if (coachByIdDTO==null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_COACH_NOT_EXIST);
            //判断教练状态是否异常
            if (coachByIdDTO.getCoachState()!= CoachState.COACH_STATE_NORMAL) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_COACH_STATE_ERROR);
            //判断查询门店是否报错
            Result<BusinessStoreDTO> businessStoreResult = businessStoreClient.selByBusinessStoreId(param.getStoreId());
            if (businessStoreResult.getCode()!=200) throw new ProductException(businessStoreResult.getCode(),businessStoreResult.getMessage());
            //获取数据
            BusinessStoreDTO businessStore = businessStoreResult.getData();
            //判断是否为空
            if (businessStore==null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_STORE_ABSENT);
            //判断场馆状态是否异常
            if (businessStore.getStoreState()== BusinessState.STORE_STATE_DELETE) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_STORE_STATE_ERROR);
            //查询出同一家场馆的所有的私教产品
            QueryWrapper<PrivateProduct> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("store_id",param.getStoreId());//该门店
            wrapper1.notIn("private_product_state", ProductState.PRIVATE_PRODUCT_STATE_DELETE);//状态不是删除
            wrapper1.eq("private_product_name",param.getPrivateProductName());//该私教产品名称
            PrivateProduct product = privateProductMapper.selectOne(wrapper1);
            //判断是否已经存在该商品
            if (product!=null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_PRIVATE_PRODUCT_NAME_NOT_REPEAT);
            //查询非删除状态下是否存在多个相同教练ID的私教产品
            QueryWrapper<PrivateProduct> wrapper2 = new QueryWrapper<>();
            wrapper2.eq("coach_id",param.getCoachId());
            wrapper2.eq("private_product_state",ProductState.PRIVATE_PRODUCT_STATE_DELETE);
            PrivateProduct selectOne = privateProductMapper.selectOne(wrapper2);
            //判断该教练是否已经存在私教产品
            if (selectOne!=null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_COACH_EXIST_PRIVATE_PRODUCT);
            //判断该教练是否属于该场馆
            if (coachByIdDTO.getStoreId()!=param.getStoreId()) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_COACH_NOT_BELONG_STORE);
            //对象转换
            PrivateProduct privateProduct = BeanUtil.toBean(param, PrivateProduct.class);
            //教练名称赋值
            privateProduct.setCoachName(coachByIdDTO.getCoachName());
            //门店名称赋值
            privateProduct.setStoreName(businessStore.getStoreName());
            //设置私教产品默认为下架 确认无误之后再上架
            privateProduct.setPrivateProductState(ProductState.PRIVATE_PRODUCT_STATE_DISABLE);
            //新增数据
            privateProductMapper.insert(privateProduct);
        }finally {
            //判断是否是自己的锁 并且还未释放
            if (lock.isLocked()){
                lock.unlock();
            }
        }
    }

    /**
     * 私教产品上架
     * @param privateProductId
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void normalPrivateProduct(Integer privateProductId) {
        PrivateProduct privateProduct = privateProductMapper.selectById(privateProductId);
        //判断是否存在
        if (privateProduct==null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_PRIVATE_PRODUCT_NOT_EXIST);
        //判断私教产品状态是否异常
        if (privateProduct.getPrivateProductState()!=ProductState.PRIVATE_PRODUCT_STATE_DISABLE) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_PRIVATE_PRODUCT_STATE_ERROR);
        //判断教练信息是否报错
        Result<CoachByIdDTO> coachByIdDTOResult = coachClient.getCoachById(privateProduct.getCoachId());
        if (coachByIdDTOResult.getCode()!=200) throw new ProductException(coachByIdDTOResult.getCode(),coachByIdDTOResult.getMessage());
        //获取数据
        CoachByIdDTO coachByIdDTO = coachByIdDTOResult.getData();
        //判断是否存在
        if (coachByIdDTO==null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_COACH_NOT_EXIST);
        //判断教练状态是否异常
        if (coachByIdDTO.getCoachState()!=CoachState.COACH_STATE_NORMAL) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_COACH_STATE_ERROR);
        //判断场馆信息是否报错
        Result<BusinessStoreDTO> businessStoreResult = businessStoreClient.selByBusinessStoreId(privateProduct.getStoreId());
        if (businessStoreResult.getCode()!=200) throw new ProductException(businessStoreResult.getCode(),businessStoreResult.getMessage());
        //获取数据
        BusinessStoreDTO businessStore = businessStoreResult.getData();
        //判断是否存在
        if (businessStore==null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_STORE_ABSENT);
        //判断场馆状态是否异常
        if (businessStore.getStoreState()==BusinessState.STORE_STATE_DELETE) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_STORE_STATE_ERROR);
        //修改成上架
        privateProduct.setPrivateProductState(ProductState.PRIVATE_PRODUCT_STATE_NORMAL);
        privateProductMapper.updateById(privateProduct);
    }

    /**
     * 私教产品下架
     * @param privateProductId
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void disablePrivateProduct(Integer privateProductId) {
        PrivateProduct privateProduct = privateProductMapper.selectById(privateProductId);
        //判断是否存在
        if (privateProduct==null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_PRIVATE_PRODUCT_NOT_EXIST);
        //判断私教产品状态是否异常
        if (privateProduct.getPrivateProductState()!=ProductState.PRIVATE_PRODUCT_STATE_NORMAL) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_PRIVATE_PRODUCT_STATE_ERROR);
        //判断教练信息是否报错
        Result<CoachByIdDTO> coachByIdDTOResult = coachClient.getCoachById(privateProduct.getCoachId());
        if (coachByIdDTOResult.getCode()!=200) throw new ProductException(coachByIdDTOResult.getCode(),coachByIdDTOResult.getMessage());
        //获取数据
        CoachByIdDTO coachByIdDTO = coachByIdDTOResult.getData();
        //判断是否存在
        if (coachByIdDTO==null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_COACH_NOT_EXIST);
        //判断教练状态是否异常
        if (coachByIdDTO.getCoachState()!=CoachState.COACH_STATE_NORMAL) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_COACH_STATE_ERROR);
        //判断场馆信息是否报错
        Result<BusinessStoreDTO> businessStoreResult = businessStoreClient.selByBusinessStoreId(privateProduct.getStoreId());
        if (businessStoreResult.getCode()!=200) throw new ProductException(businessStoreResult.getCode(),businessStoreResult.getMessage());
        //获取数据
        BusinessStoreDTO businessStore = businessStoreResult.getData();
        //判断是否存在
        if (businessStore==null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_STORE_ABSENT);
        //判断场馆状态是否异常
        if (businessStore.getStoreState()==BusinessState.STORE_STATE_DELETE) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_STORE_STATE_ERROR);
        //修改成下架
        privateProduct.setPrivateProductState(ProductState.PRIVATE_PRODUCT_STATE_DISABLE);
        privateProductMapper.updateById(privateProduct);
    }

    /**
     * 私教产品删除
     * @param privateProductId
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void deletePrivateProduct(Integer privateProductId) {
        PrivateProduct privateProduct = privateProductMapper.selectById(privateProductId);
        //判断是否存在
        if (privateProduct==null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_PRIVATE_PRODUCT_NOT_EXIST);
        //判断私教产品状态是否异常
        if (privateProduct.getPrivateProductState()==ProductState.PRIVATE_PRODUCT_STATE_DELETE) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_PRIVATE_PRODUCT_STATE_ERROR);
        //判断教练信息是否报错
        Result<CoachByIdDTO> coachByIdDTOResult = coachClient.getCoachById(privateProduct.getCoachId());
        if (coachByIdDTOResult.getCode()!=200) throw new ProductException(coachByIdDTOResult.getCode(),coachByIdDTOResult.getMessage());
        //获取数据
        CoachByIdDTO coachByIdDTO = coachByIdDTOResult.getData();
        //判断是否存在
        if (coachByIdDTO==null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_COACH_NOT_EXIST);
        //判断教练状态是否异常
        if (coachByIdDTO.getCoachState()!=CoachState.COACH_STATE_NORMAL) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_COACH_STATE_ERROR);
        //判断场馆信息是否报错
        Result<BusinessStoreDTO> businessStoreResult = businessStoreClient.selByBusinessStoreId(privateProduct.getStoreId());
        if (businessStoreResult.getCode()!=200) throw new ProductException(businessStoreResult.getCode(),businessStoreResult.getMessage());
        //获取数据
        BusinessStoreDTO businessStore = businessStoreResult.getData();
        //判断是否存在
        if (businessStore==null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_STORE_ABSENT);
        //判断场馆状态是否异常
        if (businessStore.getStoreState()==BusinessState.STORE_STATE_DELETE) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_STORE_STATE_ERROR);
        //修改成删除
        privateProduct.setPrivateProductState(ProductState.PRIVATE_PRODUCT_STATE_DELETE);
        privateProductMapper.updateById(privateProduct);
    }

    /**
     * 判断该教练是否存在私教产品
     * @param coachId
     * @return
     */
    @Override
    public PrivateProductByIdDTO checkExistByCoachId(Integer coachId) {
        QueryWrapper<PrivateProduct> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_id",coachId);
        wrapper.notIn("private_product_state",ProductState.PRIVATE_PRODUCT_STATE_DELETE);
        PrivateProduct privateProduct = privateProductMapper.selectOne(wrapper);
        //判断是否存在私教产品
        if (privateProduct!=null) {
            //对象转换 返回
            return BeanUtil.toBean(privateProduct,PrivateProductByIdDTO.class);
        }
        return null;
    }

    /**
     * 商家查询所有私教产品信息
     * @param param
     * @return
     */
    @Override
    public PageInfo queryPrivateProduct(QueryPrivateProductParam param) {
        QueryWrapper<PrivateProduct> wrapper = new QueryWrapper<>();
        wrapper.eq("store_id",param.getStoreId());//自身场馆的私教产品信息
        //私教产品名称搜索
        if (ObjectUtil.isNotEmpty(param.getPrivateProductName())){
            wrapper.like("private_product_name",param.getPrivateProductName());
        }
        //教练姓名搜索
        if (ObjectUtil.isNotEmpty(param.getCoachName())){
            wrapper.like("coach_name",param.getCoachName());
        }
        //私教最低价格搜索
        if (ObjectUtil.isNotEmpty(param.getPrivateProductPriceMin())){
            wrapper.ge("private_product_price",param.getPrivateProductPriceMin());
        }
        //私教最高价格搜索
        if (ObjectUtil.isNotEmpty(param.getPrivateProductPriceMax())){
            wrapper.le("private_product_price",param.getPrivateProductPriceMax());
        }
        //私教产品状态搜索
        if (ObjectUtil.isNotEmpty(param.getPrivateProductState())){
            wrapper.eq("private_product_state",param.getPrivateProductState());
        }
        //索引排序
        wrapper.orderByAsc("private_product_id");
        //分页查询
        Page<PrivateProduct> page = new Page<>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 5 : param.getPageSize());
        privateProductMapper.selectPage(page,wrapper);
        //集合转换
        List<QueryAllPrivateProductDTO> queryAllPrivateProductDTOS = new ArrayList<>();
        if (page.getRecords()!=null&&page.getRecords().size()>0){
            for (PrivateProduct privateProduct : page.getRecords()) {
                //对象转换
                QueryAllPrivateProductDTO queryAllPrivateProductDTO = BeanUtil.toBean(privateProduct, QueryAllPrivateProductDTO.class);
                //状态赋值
                queryAllPrivateProductDTO.setPrivateProductState(privateProduct.getPrivateProductState()==0?"已上架":privateProduct.getPrivateProductState()==1?"已下架":"已删除");
                //数据保存
                queryAllPrivateProductDTOS.add(queryAllPrivateProductDTO);
            }
        }
        //分页对象转换
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(queryAllPrivateProductDTOS);
        return pageInfo;
    }

    /**
     * 批量删除私教产品
     * @param storeId
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void removePrivateProduct(Integer storeId) {
        Result<BusinessStoreDTO> businessStoreDTOResult = businessStoreClient.selByBusinessStoreId(storeId);
        //判断是否报错
        if (businessStoreDTOResult.getCode()!=200) throw new ProductException(businessStoreDTOResult.getCode(),businessStoreDTOResult.getMessage());
        //获取数据
        BusinessStoreDTO businessStoreDTO = businessStoreDTOResult.getData();
        //判断是否存在
        if (businessStoreDTO==null) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_STORE_ABSENT);
        //判断场馆状态是否异常
        if (businessStoreDTO.getStoreState()==BusinessState.STORE_STATE_DELETE) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_STORE_STATE_ERROR);
        //通过storeId查询私教产品
        QueryWrapper<PrivateProduct> wrapper = new QueryWrapper<>();
        wrapper.eq("store_id",storeId);
        //索引排序
        wrapper.orderByAsc("private_product_id");
        List<PrivateProduct> privateProducts = privateProductMapper.selectList(wrapper);
        //判断是否存在
        if (privateProducts==null||privateProducts.size()<1) throw new ProductException(ProductExceptionCode.PRODUCT_EXCEPTION_CODE_PRIVATE_PRODUCT_NOT_EXIST);
        //遍历循环调用删除
        for (PrivateProduct privateProduct : privateProducts) {
            //删除
            this.deletePrivateProduct(privateProduct.getPrivateProductId());
        }
    }

    /**
     * 用户查询该商家的正常私教产品
     * @param param
     * @return
     */
    @Override
    public PageInfo userQueryNormalPrivateProduct(QueryNormalPrivateProductParam param) {
        QueryWrapper<PrivateProduct> wrapper = new QueryWrapper<>();
        //正常状态
        wrapper.eq("private_product_state",ProductState.PRIVATE_PRODUCT_STATE_NORMAL);
        //门店ID搜索
        if (ObjectUtil.isNotEmpty(param.getStoreId())){
            wrapper.eq("store_id",param.getStoreId());
        }
        //私教产品名称搜索
        if (ObjectUtil.isNotEmpty(param.getPrivateProductName())){
            wrapper.like("private_product_name",param.getPrivateProductName());
        }
        //教练姓名搜索
        if (ObjectUtil.isNotEmpty(param.getCoachName())){
            wrapper.like("coach_name",param.getCoachName());
        }
        //索引排序
        wrapper.orderByAsc("private_product_id");
        //分页查询
        Page<PrivateProduct> page = new Page<>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 5 : param.getPageSize());
        privateProductMapper.selectPage(page,wrapper);
        //集合数据转换
        List<NormalPrivateProductDTO> normalPrivateProductDTOS = new ArrayList<>();
        if (page.getRecords()!=null&&page.getRecords().size()>0){
            for (PrivateProduct privateProduct : page.getRecords()) {
                //对象转换
                NormalPrivateProductDTO normalPrivateProductDTO = BeanUtil.toBean(privateProduct, NormalPrivateProductDTO.class);
                //保存集合
                normalPrivateProductDTOS.add(normalPrivateProductDTO);
            }
        }
        //分页对象转换
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(normalPrivateProductDTOS);
        return pageInfo;
    }
}
